use actix_web::{get, HttpResponse, ResponseError};
use actix_web::body::BoxBody;
use actix_web::http::{header, StatusCode};
use actix_web::http::header::ContentType;
use derive_more::{Display, Error};

#[derive(Debug,Display,Error)]
enum UserError{

    #[display(fmt="Validation error on field: {}",field)]
    ValidationError{field: String},

}

impl ResponseError for UserError{

    fn status_code(&self) -> StatusCode {
        match *self { UserError::ValidationError { .. } => StatusCode::BAD_REQUEST }
    }

    fn error_response(&self) -> HttpResponse<BoxBody> {
        HttpResponse::build(self.status_code())
            .insert_header(ContentType::html())
            .body(self.to_string())
    }
}

#[derive(Debug,Display,Error)]
enum SystemError{
    #[display(fmt = "An internal error occurred. Please try again later.")]
    InternalError,
}

impl ResponseError for SystemError{
    fn status_code(&self) -> StatusCode {
        match *self { SystemError::InternalError => StatusCode::INTERNAL_SERVER_ERROR }
    }

    fn error_response(&self) -> HttpResponse<BoxBody> {
        HttpResponse::build(self.status_code())
            .insert_header(ContentType::html())
            .body(self.to_string())
    }
}

#[get("/")]
async fn index()->Result<&'static str, SystemError>{
    // 将用户错误转换为系统错误(仅演示转换)
    do_thing_that_fails().map_err(|_e|SystemError::InternalError)?;
    Ok("")
}

fn do_thing_that_fails() -> Result<(), UserError> {
    Err(UserError::ValidationError {field:String::from("bad")})
}

fn main() {}